/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.business.service.shop.impl;

import cn.hutool.core.util.IdUtil;
import com.shop.cereshop.business.dao.shop.CereShopQualificationFlowDAO;
import com.shop.cereshop.business.param.shop.ShopCertificationFlowParam;
import com.shop.cereshop.business.page.shop.*;
import com.shop.cereshop.business.service.business.CerePlatformBusinessService;
import com.shop.cereshop.business.service.shop.*;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.business.CereBusinessShop;
import com.shop.cereshop.commons.domain.business.CerePlatformBusiness;
import com.shop.cereshop.commons.domain.shop.*;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.domain.im.tx.resp.ocr.BizLicenseOCRResp;
import com.shop.cereshop.commons.domain.im.tx.resp.ocr.IdCardOCRResp;
import com.shop.cereshop.commons.service.ocr.TencentOCRService;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 店铺认证流程服务实现类
 */
@Slf4j
@Service
public class ShopCertificationFlowServiceImpl implements ShopCertificationFlowService {

    @Autowired
    private CerePlatformBusinessService cerePlatformBusinessService;
    @Autowired
    private CereShopQualificationFlowDAO cereShopQualificationFlowDAO;
    @Autowired
    private CerePlatformShopService cerePlatformShopService;

    @Autowired
    private CereShopEnterpriseService cereShopEnterpriseService;

    @Autowired
    private CereShopIndividualBusinessesService cereShopIndividualBusinessesService;

    @Autowired
    private CereShopBrandService cereShopBrandService;

    @Autowired
    private CereShopOtherOrganizationsService cereShopOtherOrganizationsService;

    @Autowired
    private TencentOCRService tencentOCRService;

    @Autowired
    private CereShopLogoTitleService cereShopLogoTitleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RecognizeResp recognize(ShopCertificationFlowParam param) throws CoBusinessException {


        String flowId = IdUtil.simpleUUID();
        BizLicenseOCRResp businessLicenseResult = tencentOCRService.bizLicenseOCRByUrl(param.getBusinessLicenseUrl());
        if (EmptyUtils.isEmpty(businessLicenseResult)) {
            throw new CoBusinessException(CoReturnFormat.OCR_RECOGNITION_FAILED);
        }
      if(businessLicenseResult.getRequestId().equals("ERROR")){
            throw new CoBusinessException(businessLicenseResult.getErrorMsg());
        }
        Map<String, IdCardOCRResp> idCardResult = tencentOCRService.idCardOCRBothSidesByUrl(param.getIdCardFrontUrl(), param.getIdCardBackUrl());
        if (EmptyUtils.isEmpty(idCardResult) || EmptyUtils.isEmpty(idCardResult.get("front"))) {
            throw new CoBusinessException(CoReturnFormat.OCR_RECOGNITION_FAILED);
        }
        if (idCardResult.get("front").getRequestId().equals("ERROR")) {
            throw new CoBusinessException(idCardResult.get("front").getErrorMsg());
        }

        if (idCardResult.get("back").getRequestId().equals("ERROR")) {
            throw new CoBusinessException(idCardResult.get("front").getErrorMsg());
        }
        // TODO: 记录流程到库
        CereShopQualificationFlow flow = new CereShopQualificationFlow();
        flow.setFlowId(flowId);
        flow.setBusinessAddress(param.getBusinessAddress());
        flow.setShopType(param.getShopType());
        flow.setFlowStatus(2);
        flow.setBusinessLicenseUrl(param.getBusinessLicenseUrl());
        flow.setIdCardFrontUrl(param.getIdCardFrontUrl());
        flow.setIdCardBackUrl(param.getIdCardBackUrl());
        flow.setCreateTime(TimeUtils.yyMMddHHmmss());
        flow.setUpdateTime(TimeUtils.yyMMddHHmmss());
        flow.setApplicantName(param.getApplicantName());
        flow.setIdCardNumber(param.getIdCardNumber());
        flow.setPhoneNumber(param.getPhoneNumber());
        flow.setOcrResult(com.alibaba.fastjson.JSONObject.toJSONString(businessLicenseResult));
        cereShopQualificationFlowDAO.insert(flow);
        RecognizeResp resp = new RecognizeResp();
        resp.setFlowId(flowId);
        resp.setFlowStatus(2);
        resp.setBusinessLicenseResult(businessLicenseResult);
        resp.setIdCardResult(idCardResult);
        resp.setMessage("OCR识别完成，请开始认证流程");
        return resp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StartFlowResp start(ShopCertificationFlowParam param, CerePlatformBusiness user) throws CoBusinessException {
        if (EmptyUtils.isEmpty(user)) {
            throw new CoBusinessException(CoReturnFormat.USER_NOT_LOGIN);
        }
        StartFlowResp resp = new StartFlowResp();
        resp.setFlowId(param.getFlowId());
        resp.setFlowStatus(3);
        resp.setMessage("认证流程开始，请进行人脸识别");
        return resp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SimpleFlowResp faceRecognition(ShopCertificationFlowParam param, CerePlatformBusiness user) throws CoBusinessException {
        if (EmptyUtils.isEmpty(user)) {
            throw new CoBusinessException(CoReturnFormat.USER_NOT_LOGIN);
        }
        SimpleFlowResp resp = new SimpleFlowResp();
        resp.setFlowId(param.getFlowId());
        resp.setFlowStatus(4);
        resp.setMessage("人脸识别完成，可以完成认证");
        return resp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CompleteResp complete(ShopCertificationFlowParam param, CerePlatformBusiness user) throws CoBusinessException {
        if (EmptyUtils.isEmpty(user)) {
            throw new CoBusinessException(CoReturnFormat.USER_NOT_LOGIN);
        }
        CerePlatformShop shop = new CerePlatformShop();
        shop.setShopCode(IdUtil.simpleUUID());
        shop.setShopName(param.getCompanyName() != null ? param.getCompanyName() : param.getMerchantName());
        shop.setShopPhone(param.getPhoneNumber());
        shop.setShopPassword(IdUtil.simpleUUID());
        shop.setChargePersonName(param.getApplicantName());
        shop.setChargePersonPhone(param.getPhoneNumber());
        shop.setShopAdress(param.getBusinessAddress());
        shop.setAuthenType(param.getShopType());
        shop.setAuthenticationState(2);
        shop.setCheckState(0);
        shop.setState(1);
        String time = TimeUtils.yyMMddHHmmss();
        shop.setCreateTime(TimeUtils.parseToLocalDateTime(time));
        shop.setUpdateTime(TimeUtils.parseToLocalDateTime(time));
        // 新增字段
        shop.setIsCityStore(param.getIsCityStore());
        shop.setIsOnlineStore(param.getIsOnlineStore());
        shop.setIsInStore(param.getIsInStore());
        shop.setCityStoreDistance(param.getCityStoreDistance());
        shop.setCityStoreIsserving(param.getCityStoreIsserving());

        cerePlatformShopService.insert(shop);
        createCertificationInfo(shop.getShopId(), param);

        // 保存店铺头像标题
        saveShopLogoTitle(shop.getShopId(), param);

        CereBusinessShop businessShop = new CereBusinessShop();
        businessShop.setBusinessUserId(user.getBusinessUserId());
        businessShop.setShopId(shop.getShopId());
        businessShop.setIfBinding(1);
        CompleteResp resp = new CompleteResp();
        resp.setShopId(shop.getShopId());
        resp.setShopName(shop.getShopName());
        resp.setMessage("店铺创建成功，等待平台审核");
        return resp;
    }

    @Override
    public SimpleFlowResp getStatus(String flowId, CerePlatformBusiness user) throws CoBusinessException {
        if (EmptyUtils.isEmpty(user)) {
            throw new CoBusinessException(CoReturnFormat.USER_NOT_LOGIN);
        }
        SimpleFlowResp resp = new SimpleFlowResp();
        resp.setFlowId(flowId);
        resp.setFlowStatus(1);
        resp.setMessage("查询成功");
        return resp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SimpleFlowResp cancel(String flowId, CerePlatformBusiness user) throws CoBusinessException {
        if (EmptyUtils.isEmpty(user)) {
            throw new CoBusinessException(CoReturnFormat.USER_NOT_LOGIN);
        }
        SimpleFlowResp resp = new SimpleFlowResp();
        resp.setFlowId(flowId);
        resp.setMessage("认证流程已取消");
        return resp;
    }

    private void createCertificationInfo(Long shopId, ShopCertificationFlowParam param) throws CoBusinessException {
        String time = TimeUtils.yyMMddHHmmss();
        switch (param.getShopType()) {
            case 1:
                CereShopEnterprise enterprise = new CereShopEnterprise();
                enterprise.setShopId(shopId);
                enterprise.setEnterpriseName(param.getCompanyName());
                enterprise.setEnterpriseCode(param.getSocialCreditCode());
                enterprise.setEnterpriseOperator(param.getApplicantName());
                enterprise.setEnterpriseIdCard(param.getIdCardNumber());
                enterprise.setEnterpriseCardPositive(param.getIdCardFrontUrl());
                enterprise.setEnterpriseCardSide(param.getIdCardBackUrl());
                enterprise.setEnterpriseLicense(param.getBusinessLicenseUrl());
                enterprise.setEnterpriseAdress(param.getBusinessAddress());
                enterprise.setServicePhone(param.getPhoneNumber());
                enterprise.setCreateTime(time);
                enterprise.setUpdateTime(time);
                cereShopEnterpriseService.enterprise(enterprise, null);
                break;
            case 2:
                CereShopIndividualBusinesses individual = new CereShopIndividualBusinesses();
                individual.setShopId(shopId);
                individual.setSubjectName(param.getMerchantName());
                individual.setSubjectCode(param.getSocialCreditCode());
                individual.setSubjectOperator(param.getApplicantName());
                individual.setSubjectIdCard(param.getIdCardNumber());
                individual.setSubjectCardPositive(param.getIdCardFrontUrl());
                individual.setSubjectCardSide(param.getIdCardBackUrl());
                individual.setSubjectLicense(param.getBusinessLicenseUrl());
                individual.setSubjectAdress(param.getBusinessAddress());
                individual.setServicePhone(param.getPhoneNumber());
                individual.setCreateTime(time);
                individual.setUpdateTime(time);
                cereShopIndividualBusinessesService.individual(individual, null);
                break;
            case 3:
                CereShopBrand brand = new CereShopBrand();
                brand.setShopId(shopId);
                brand.setBrandName(param.getBrandName());
                brand.setBrandAuthorizationUrl(param.getBrandAuthorizationUrl());
                brand.setTrademarkCertificateUrl(param.getTrademarkCertificateUrl());
                brand.setBrandAddress(param.getBusinessAddress());
                brand.setBrandContactPerson(param.getApplicantName());
                brand.setBrandContactPhone(param.getPhoneNumber());
                brand.setBrandRegistrationNumber(param.getSocialCreditCode());
                brand.setCreateTime(time);
                brand.setUpdateTime(time);
                brand.setBrandStatus(1);
                cereShopBrandService.insert(brand);
                break;
            case 4:
                CereShopOtherOrganizations organization = new CereShopOtherOrganizations();
                organization.setShopId(shopId);
                organization.setOtherName(param.getCompanyName());
                organization.setOtherCode(param.getSocialCreditCode());
                organization.setOtherOperator(param.getApplicantName());
                organization.setOtherIdCard(param.getIdCardNumber());
                organization.setOtherCardPositive(param.getIdCardFrontUrl());
                organization.setOtherCardSide(param.getIdCardBackUrl());
                organization.setOtherLicense(param.getBusinessLicenseUrl());
                organization.setOtherAdress(param.getBusinessAddress());
                organization.setServicePhone(param.getPhoneNumber());
                organization.setCreateTime(time);
                organization.setUpdateTime(time);
                cereShopOtherOrganizationsService.organizations(organization, null);
                break;
            default:
                throw new CoBusinessException("不支持的店铺类型");
        }
    }

    /**
     * 保存店铺头像标题
     * @param shopId 店铺ID
     * @param param 认证流程参数
     */
    private void saveShopLogoTitle(Long shopId, ShopCertificationFlowParam param) throws CoBusinessException {
        if (shopId == null) {
            return;
        }

        // 检查是否需要上传头像标题
        boolean needCityStore = param.getIsCityStore() != null && param.getIsCityStore() == 1;
        boolean needOnlineStore = param.getIsOnlineStore() != null && param.getIsOnlineStore() == 1;
        boolean needInStore = param.getIsInStore() != null && param.getIsInStore() == 1;

        if (!needCityStore && !needOnlineStore && !needInStore) {
            // 如果都不支持，不需要上传头像标题
            return;
        }

        // 验证必须上传头像标题
        if (EmptyUtils.isEmpty(param.getLogoTitleList())) {
            throw new CoBusinessException("请上传店铺头像标题信息");
        }

        // 验证数量（最多3个）
        if (param.getLogoTitleList().size() > 3) {
            throw new CoBusinessException("店铺头像标题最多只能上传3个");
        }

        // 验证每个支持的类型都有对应的数据
        Set<Integer> providedTypes = new HashSet<>();
        for (CereShopLogoTitle logoTitle : param.getLogoTitleList()) {
            if (logoTitle.getType() == null) {
                throw new CoBusinessException("店铺头像标题的类型不能为空");
            }
            if (logoTitle.getType() < 1 || logoTitle.getType() > 3) {
                throw new CoBusinessException("店铺头像标题的类型只能是1(同城购)、2(电商购)、3(到店核销)");
            }
            if (EmptyUtils.isEmpty(logoTitle.getLogo())) {
                throw new CoBusinessException("店铺头像不能为空");
            }
            if (EmptyUtils.isEmpty(logoTitle.getTitle())) {
                throw new CoBusinessException("店铺标题不能为空");
            }
            providedTypes.add(logoTitle.getType());
        }

        // 验证必须的类型都已提供
        if (needCityStore && !providedTypes.contains(1)) {
            throw new CoBusinessException("支持同城购时，必须上传type=1的店铺头像标题");
        }
        if (needOnlineStore && !providedTypes.contains(2)) {
            throw new CoBusinessException("支持电商购时，必须上传type=2的店铺头像标题");
        }
        if (needInStore && !providedTypes.contains(3)) {
            throw new CoBusinessException("支持到店核销时，必须上传type=3的店铺头像标题");
        }

        // 保存数据
        cereShopLogoTitleService.saveBatch(shopId, param.getLogoTitleList());
    }
}
